﻿using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Reflection;
using System.Linq.Expressions;
using System;

namespace DataLayer.Generic
{
    [System.ComponentModel.DataObject]
    public class StaticGenericRepository<TEntity, TDataContext>
        where TDataContext : DataContext, new()
        where TEntity : class
    {
        private static readonly IGenericRepository<TEntity, TDataContext> repository = new GenericRepository<TEntity, TDataContext>();

        #region Generic Object Data Source
        public static TDataContext DataContext
        {
            get
            {
                return repository.DataContext;
            }
        }

        public static string PrimaryKeyName
        {
            get
            {
                return repository.PrimaryKeyName;
            }
        }

        protected static PropertyInfo PrimaryKey
        {
            get
            {
                return repository.PrimaryKey;
            }
        }

        protected static object GetPrimaryKeyValue(TEntity entity)
        {
            return PrimaryKey.GetValue(entity, null);
        }
        public static void DiscardDataContext()
        {
            repository.DiscardDataContext();
        }
        public static void SubmitChanges()
        {
            repository.SubmitChanges();
        }

        #endregion

        #region Generic CRUD methods
        //---------------------Selects----------------------------------
        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public static IQueryable<TResult> Select<TResult>(Expression<Func<TEntity, TResult>> selector)
        {
            return repository.Select(selector);
        }
        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public static IQueryable<TEntity> SelectAll()
        {
            return repository.SelectAll();
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public static IQueryable<TEntity> SelectAll(string sortExpression)
        {
            return repository.SelectAll(sortExpression);
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public static IQueryable<TEntity> SelectAll(string sortExpression, int maximumRows, int startRowIndex)
        {
            return repository.SelectAll(sortExpression, maximumRows, startRowIndex);
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public static IQueryable<TEntity> SelectAll(int maximumRows, int startRowIndex)
        {
            return repository.SelectAll(maximumRows, startRowIndex);
        }

        public static int Count()
        {
            return repository.Count();
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public static List<TEntity> SelectAllAsList()
        {
            return SelectAll().ToList();
        }

        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
        public static TEntity GetEntity(object id)
        {
            return repository.GetEntity(id);
        }

        //----------------------Insert------------------------------------
        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Insert)]
        public static object Insert(TEntity entity)
        {
            return repository.Insert(entity);
        }

        public static object Insert(TEntity entity, bool submitChanges)
        {
            return repository.Insert(entity, submitChanges);
        }

        //-----------------------Update-----------------------------------------
        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Update)]
        public static void Update(TEntity entity)
        {
            repository.Update(entity);
        }

        public static void Update(TEntity entity, bool submitChanges)
        {
            repository.Update(entity, submitChanges);
        }
        public static void Update(TEntity entity, bool submitChanges, bool includeChildren)
        {
            repository.Update(entity, submitChanges, includeChildren);
        }
        public static void Update(TEntity entity, bool submitChanges, bool includeChildren, int maxLevels)
        {
            repository.Update(entity, submitChanges, includeChildren, maxLevels);
        }

        //----------------------Delete-------------------------------------------
        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Delete)]
        public void Delete(int id)
        {
            repository.Delete(id);
        }
        [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Delete)]
        public static void Delete(TEntity entity)
        {
            repository.Delete(entity);
        }

        public static void Delete(TEntity entity, bool submitChanges)
        {
            repository.Delete(entity, submitChanges);
        }
        #endregion
    }
}
